package com.cardmanager.pro.authorization;

import java.math.BigDecimal;
import java.net.URI;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.cardmanager.pro.util.CommonsUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.cardmanager.pro.business.ConsumeTaskPOJOBusiness;
import com.cardmanager.pro.business.CreditCardAccountBusiness;
import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;
import com.cardmanager.pro.pojo.CreditCardAccount;
import com.cardmanager.pro.util.RestTemplateUtil;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.DateUtil;
import net.sf.json.JSONObject;

@Component
public class CreditCardManagerAuthorizationHandle {

	private final Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	private RestTemplateUtil util;

	@Autowired
	private CreditCardAccountBusiness creditCardAccountBusiness;

	@Autowired
	private RepaymentTaskPOJOBusiness repaymentTaskPOJOBusiness;

	@Autowired
	private ConsumeTaskPOJOBusiness consumeTaskPOJOBusiness;

	/**
	 * 查询use模块银行卡信息和汇率信息
	 * @param cardNo
	 *
	 */
	public Map verifyBankInfo(String cardNo,long userId,String idDef,String channelId){
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("user", "error url request");
		String url = uri.toString() + "/v1.0/user/register/bankInfo";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("cardNo", cardNo);
		requestEntity.add("userId", userId + "");
		requestEntity.add("idDef", idDef);
		requestEntity.add("payType", "2");
		requestEntity.add("channelType", channelId);
		String resultString = restTemplate.postForObject(url, requestEntity, String.class);
		Map map = JSONObject.fromObject(resultString);
		return map;
	}

	/**
	 * 验证是否是可用信用卡
	 * @param userId
	 * @param creditCardNumber
	 * @return 返回JSON对象,根据对象中的resp_code判断是否为可用信用卡,000000为可用,999999为不可用
	 */
	public Map verifyCreditCard(String userId,String creditCardNumber){
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("user", "error url request");
		String url = uri.toString() + "/v1.0/user/bank/verify/isuseable";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("userId", userId);
		requestEntity.add("bankCardNumber", creditCardNumber);
		requestEntity.add("cardType", "0");
		String resultString = restTemplate.postForObject(url, requestEntity, String.class);
		Map map = JSONObject.fromObject(resultString);
		return map;
	}

	/**
	 * 验证是否注册
	 * @param userId
	 *
	 */
	public Map verifyRegister(String userId,String creditCardNumber,String channelId,String payType){
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("user", "error url request");
		String url = uri.toString() + "/v1.0/user/register/bankInfo";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("userId", userId);
		requestEntity.add("channelType", channelId);
		requestEntity.add("cardNo", creditCardNumber);
		requestEntity.add("payType", payType);
		String resultString = restTemplate.postForObject(url, requestEntity, String.class);
		Map map = JSONObject.fromObject(resultString);
		return map;
	}

	/**
	 * 验证是否注册
	 * @param userId
	 * @param creditCardNumber
	 * @return 000000为已注册,999999为未注册
	 */
	public Map<String,Object> verifyIsRegister(String userId,String creditCardNumber){
		Map<String,Object>map = new HashMap<>();
		CreditCardAccount creditCardAccount = creditCardAccountBusiness.findByUserIdAndCreditCardNumber(userId,creditCardNumber);
		if(creditCardAccount==null){
			map.put(CommonConstants.RESP_MESSAGE,"无该卡数据,需要进行首笔验证!");
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
		}else{
			map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
			map.put(CommonConstants.RESP_MESSAGE, "验证成功,可进入生成还款计划!");
		}
		map.put(CommonConstants.RESULT, creditCardAccount);
		return map;
	}

	/**
	 * 验证是否完成首笔还款任务
	 * @param userId
	 * @param creditCardNumber
	 * @return
	 */
	public Map<String,Object> verifyIsCompletedFirstRepaymentTask(String userId,String creditCardNumber){
		Map<String,Object>map = new HashMap<>();
		int count = repaymentTaskPOJOBusiness.findByOrderStatus1AndTaskType0Count(userId,creditCardNumber);
		if(count == 0){
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "未完成首笔还款任务!");
			return map;
		}else{
			map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
			map.put(CommonConstants.RESP_MESSAGE, "验证成功!");
		}
		return map;
	}

	/**
	 * 验证是否有待执行消费任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false为无待执行消费任务,true为有待执行消费任务
	 */
	public boolean verifyDoesHaveTaskStatus0ConsumeTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int consumeTaskStatus0Count = consumeTaskPOJOBusiness.queryTaskStatus0Count(userId,creditCardNumber,0);
		if(consumeTaskStatus0Count != 0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 *  验证是否有待执行还款任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无待执行还款任务,true为有待执行还款任务
	 */
	public boolean verifyDoesHaveTaskStatus0RepaymentTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int repaymentTaskStatus0Count = repaymentTaskPOJOBusiness.queryTaskStatus0Count(userId,creditCardNumber,0);
		if(repaymentTaskStatus0Count != 0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否有首次生成的待执行消费任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无待执行消费任务,true为有待执行消费任务
	 */
	public boolean verifyDoesHaveTaskStatus0AndTaskType0ConsumeTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int consumeTaskStatus0TaskType0Count = consumeTaskPOJOBusiness.queryTaskStatus0AndTaskType0Count(userId,creditCardNumber,0,0);
		log.info("验证是否有首次生成的待执行消费任务size{}",consumeTaskStatus0TaskType0Count);
		if(consumeTaskStatus0TaskType0Count !=0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否有首次生成且执行成功的消费任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无首次生成且执行成功的消费任务,true为有首次生成且执行成功的消费任务
	 */
	public boolean verifyDoesHaveOrderStatus1AndTaskType0ConsumeTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int consumeTaskOrderStatus1AndTaskType0Count = consumeTaskPOJOBusiness.queryOrderStatus1AndTaskType0Count(userId,creditCardNumber,1,0);
		log.info("验证是否有首次生成且执行成功的消费任务size{}",consumeTaskOrderStatus1AndTaskType0Count);
		if(consumeTaskOrderStatus1AndTaskType0Count !=0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否有首次生成且执行成功的还款任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无首次生成且执行成功的还款任务,true为有首次生成且执行成功的还款任务
	 */
	public boolean verifyDoesHaveOrderStatus1AndTaskType0RepaymentTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int repaymentOrderStatus1TaskType0Count = repaymentTaskPOJOBusiness.queryOrderStatus1AndTaskType0Count(userId,creditCardNumber,1,0);
		if(repaymentOrderStatus1TaskType0Count != 0){
			isTrue = true;
		}
		return isTrue;
	}


	/**
	 * 验证是否有首次生成的待执行还款任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无待执行还款任务,true为有待执行还款任务
	 */
	public boolean verifyDoesHaveTaskStatus0AndTaskType0RepaymentTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int repaymentTaskStatus0TaskType0Count = repaymentTaskPOJOBusiness.queryTaskStatus0AndTaskType0Count(userId,creditCardNumber,0,0);
		if(repaymentTaskStatus0TaskType0Count != 0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否有批量生成的待执行消费任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无待执行消费任务,true为有待执行消费任务
	 */
	public boolean verifyDoesHaveTaskStatus0AndTaskType2ConsumeTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int consumeTaskStatus0TaskType2Count = consumeTaskPOJOBusiness.queryTaskStatus0AndTaskType0Count(userId,creditCardNumber,0,2);
		if(consumeTaskStatus0TaskType2Count != 0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否有批量生成的待执行还款任务
	 * @param userId
	 * @param creditCardNumber
	 * @return false 为无待执行消费任务,true为有待执行消费任务
	 */
	public boolean verifyDoesHaveTaskStatus0AndTaskType2RepaymentTaskPOJO(String userId,String creditCardNumber){
		boolean isTrue = false;
		int repaymentTaskStatus0TaskType2Count = repaymentTaskPOJOBusiness.queryTaskStatus0AndTaskType0Count(userId,creditCardNumber,0,2);
		if(repaymentTaskStatus0TaskType2Count != 0){
			isTrue = true;
		}
		return isTrue;
	}

	/**
	 * 验证是否是合法金额并返回指定BigDecimal格式数据
	 * @param amountStr
	 * @return
	 */
	public Map<String,Object> verifyMoney(String amountStr,int scale,int bigDecimalRound){
		Map<String,Object>map = new HashMap<>();
		amountStr = amountStr.trim();
		BigDecimal amount;
		try {
			amount = new BigDecimal(amountStr).setScale(scale, bigDecimalRound);
		} catch (Exception e) {
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "您输入的金额有误,请重新输入!");
			return map;
		}

		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "验证成功");
		map.put(CommonConstants.RESULT, amount);
		return map;
	}

	/**
	 * 验证是否是合法时间日期并返回指定格式的时间日期
	 * @param dateStr
	 * @param pattern
	 * @return
	 */
	public Map<String,Object> verifyDate(String dateStr,String pattern){
		Map<String,Object> map = new HashMap<>();
		Date date = null;
		try {
			date = DateUtil.getDateStringConvert(new Date(), dateStr, pattern);
		} catch (Exception e) {
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "您输入的日期格式不正确,请重新输入!");
			return map;
		}
		map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
		map.put(CommonConstants.RESP_MESSAGE, "验证成功");
		map.put(CommonConstants.RESULT, date);
		return map;
	}

	/**
	 * 验证String是否是空字符串或null
	 * @param fileds
	 * @return
	 */
	public Map<String,Object> verifyStringFiledIsNull(String ...fileds){
		for(String str:fileds){
			if(StringUtils.isNotBlank(str)){
				str = str.trim();
			}
			if(StringUtils.isBlank(str)){
				return CommonsUtil.returnError(CommonConstants.FALIED ,"参数不能为空");
			}
		}
		return CommonsUtil.returnSuccess("");
	}

	/**
	 * 验证信用卡是否填写有效期和安全码
	 * @param userId
	 * @param creditCardNumber
	 * @return
	 */
	public Map<String,Object> verifyCreditCardDoesHaveSecurityCodeAndExpiredTime(String userId,String creditCardNumber){

		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("user", "error url request");

		//验证信用卡是否填写有效期和安全码
		String url = uri.toString() + "/v1.0/user/bank/verify/cecuritycode/expiredtime";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("userId", userId);
		requestEntity.add("creditCardNumber", creditCardNumber);
		String resultString = restTemplate.postForObject(url, requestEntity, String.class);
		JSONObject resultJSONObject = JSONObject.fromObject(resultString);

		if(!CommonConstants.SUCCESS.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){
			return CommonsUtil.returnError("999997" ,"有效期/安全码/账单日/还款日不能为空!");
		}

		resultJSONObject = resultJSONObject.getJSONObject(CommonConstants.RESULT);
		String securityCode = resultJSONObject.getString("securityCode");
		String expiredTime = resultJSONObject.getString("expiredTime");
		String billDay = resultJSONObject.getString("billDay");
		String repaymentDay = resultJSONObject.getString("repaymentDay");
		//验证String是否是空字符串或null
		Map<String, Object> pram = this.verifyStringFiledIsNull(securityCode,expiredTime);
		if(!CommonConstants.SUCCESS.equals(pram.get(CommonConstants.RESP_CODE)) || "0".equals(billDay) || "0".equals(repaymentDay)){
			return CommonsUtil.returnError("999997" ,"有效期/安全码/账单日/还款日不能为空!");
		}
		return CommonsUtil.returnSuccess(resultJSONObject);
	}


	public void verifyCreditCardNeed(String channelTag,String userId,String creditCardNumber, String brandId){
		log.info("=== start verifyCreditCardNeedBind ==");
		Map<String,Object>map = new HashMap<>();
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("paymentchannel", "error url request");
		String url = uri.toString() + "/v1.0/paymentchannel/creditcard/verify/bind/card";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("channelTag", channelTag);
		requestEntity.add("userId", userId);
		requestEntity.add("creditCardNumber", creditCardNumber);
		requestEntity.add("brandId", brandId);
		JSONObject resultJSONObject;
		try {
			log.info("=== start v1.0/paymentchannel/creditcard/verify/bind/card ==" + channelTag);
			String resultString = restTemplate.postForObject(url, requestEntity, String.class);
			resultJSONObject = JSONObject.fromObject(resultString);
			log.info("=== verifyCreditCardNeedBind :request v1.0/paymentchannel/creditcard/verify/bind/card ==" + resultString);

			if(CommonConstants.STATUS_INVALID.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){

				// 点击确定进入授权页面 = 999996
				map.put(CommonConstants.RESP_CODE, "999996");

				if (resultJSONObject.getString("returnHtml") == null || "".equals(resultJSONObject.getString("returnHtml"))) {
					map.put("isurl", 1);
					map.put(CommonConstants.RESULT, resultJSONObject.getString("url"));
				}else{
					map.put("isurl", 0);
					map.put(CommonConstants.RESULT, resultJSONObject.getString("returnHtml"));
				}
				map.put(CommonConstants.RESP_MESSAGE, "首次使用需进行绑卡授权,点击确定进入授权页面!");

			}else if(CommonConstants.STATUS_VALID.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){

				map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
				map.put(CommonConstants.RESP_MESSAGE, "验证通过,卡已绑定成功!");
			}else{
				log.info("绑卡授权 结果: " + resultJSONObject.getString(CommonConstants.RESP_CODE) + " - " + resultJSONObject.getString(CommonConstants.RESP_MESSAGE));
				//map.put(CommonConstants.RESP_CODE, resultJSONObject.getString(CommonConstants.RESP_CODE));
				map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
				map.put(CommonConstants.RESP_MESSAGE, resultJSONObject.getString(CommonConstants.RESP_MESSAGE));
			}
		} catch (Exception e) {
			log.info("=== fail v1.0/paymentchannel/creditcard/verify/bind/card ==" +e.getMessage());
			e.printStackTrace();
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "服务器繁忙,请稍后重试!");
		}
	}


	/**
	 * 查询通道是否要先绑卡操作
	 * resp_code :
	 *   OK =  CommonConstants.SUCCESS 授权通过
	 *
	 *   Fail =  999996 需要绑卡操作, 前端将跳转到银行绑卡收银台
	 *           CommonConstants.FALIED 请求出错
	 * */
	public Map<String,Object> verifyCreditCardNeedBind(String channelTag,String userId,String creditCardNumber, String brandId){
		log.info("=== start verifyCreditCardNeedBind ==");
		Map<String,Object>map = new HashMap<>();
		RestTemplate restTemplate = new RestTemplate();
		URI uri = util.getServiceUrl("paymentchannel", "error url request");
		String url = uri.toString() + "/v1.0/paymentchannel/creditcard/verify/bind/card";
		LinkedMultiValueMap<String,String> requestEntity = new LinkedMultiValueMap<String,String>();
		requestEntity.add("channelTag", channelTag);
		requestEntity.add("userId", userId);
		requestEntity.add("creditCardNumber", creditCardNumber);
		requestEntity.add("brandId", brandId);
		JSONObject resultJSONObject;
		try {
			log.info("=== start v1.0/paymentchannel/creditcard/verify/bind/card ==" + channelTag);
			String resultString = restTemplate.postForObject(url, requestEntity, String.class);
			resultJSONObject = JSONObject.fromObject(resultString);
			log.info("=== verifyCreditCardNeedBind :request v1.0/paymentchannel/creditcard/verify/bind/card ==" + resultString);

			if(CommonConstants.STATUS_INVALID.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){

				// 点击确定进入授权页面 = 999996
				map.put(CommonConstants.RESP_CODE, "999996");

				if (resultJSONObject.getString("returnHtml") == null || "".equals(resultJSONObject.getString("returnHtml"))) {
					map.put("isurl", 1);
					map.put(CommonConstants.RESULT, resultJSONObject.getString("url"));
				}else{
					map.put("isurl", 0);
					map.put(CommonConstants.RESULT, resultJSONObject.getString("returnHtml"));
				}
				map.put(CommonConstants.RESP_MESSAGE, "首次使用需进行绑卡授权,点击确定进入授权页面!");

			}else if(CommonConstants.STATUS_VALID.equals(resultJSONObject.getString(CommonConstants.RESP_CODE))){

				map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
				map.put(CommonConstants.RESP_MESSAGE, "验证通过,卡已绑定成功!");
			}else{
				log.info("绑卡授权 结果: " + resultJSONObject.getString(CommonConstants.RESP_CODE) + " - " + resultJSONObject.getString(CommonConstants.RESP_MESSAGE));
				//map.put(CommonConstants.RESP_CODE, resultJSONObject.getString(CommonConstants.RESP_CODE));
				map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
				map.put(CommonConstants.RESP_MESSAGE, resultJSONObject.getString(CommonConstants.RESP_MESSAGE));
			}
			return map;
		} catch (Exception e) {
			log.info("=== fail v1.0/paymentchannel/creditcard/verify/bind/card ==" +e.getMessage());
			e.printStackTrace();
			map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
			map.put(CommonConstants.RESP_MESSAGE, "服务器繁忙,请稍后重试!");
			return map;
		}
	}
}
